﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AppServidor
{
   public class Pista
    {
        int duracionms;

        public int Duracionms
        {
            get { return duracionms; }
            set { duracionms = value; }
        }
        string nombre;

        public string Nombre
        {
            get { return nombre; }
            set { nombre = value; }
        }

        public override string ToString() {
            return nombre + "\t-\t" +duracionms + "ms";
        }
        public static Pista abrir(string nombre) {
               string path= System.IO.Path.Combine(@"C:\FistProjectOLC2\Tracks", nombre+".bin");
            FileInfo f= new FileInfo(path);

            if (f.Exists) {
                try
                {
                    Pista p = new Pista();
                    p.nombre = nombre;
                    FileStream fs = new FileStream(path, FileMode.Open);

                    BinaryReader br= new BinaryReader(fs, ASCIIEncoding.UTF8);
                    while (br.PeekChar() != -1) {
                        int canal=br.ReadInt32();
                        int octava=br.ReadInt32();
                        int nota=br.ReadInt32();
                        int tiempo=br.ReadInt32();
                        p.add(nota, octava, tiempo, canal);
                    }
                    p.calcularTiempo();
                    br.Close();
                    return p;
                }
                catch (System.Exception)
                {
                    return null;
                }
            
            }


            return null;
        }

        public string generarCodigo() {
            string lista = "";
          
            foreach (NotaReproducida nota in this.Notasmusicales) {
                if (nota.Nota == -10)
                {

                    lista += "\t\tEsperar(" + nota.Tiempo + "," + nota.Canal + ")\n";
                }
                else
                {
                    lista += "\t\tReproducir (" + IntrumentoMusical.Nota_num_to_txt(nota.Nota) + ", " + nota.Octava + "," + nota.Tiempo + ", " + nota.Canal + ")\n";
                }
                
            }
          
        

           

            String script = "Pista " +this.nombre+"\n\t"+
                        "Principal()\n" +
                        lista;
            return script;
        
        }

        public string generarXmlCodigo()
        {
            Dictionary<int, string> tiempo_canal = new Dictionary<int, string>();
            foreach (NotaReproducida nota in notasmusicales){
              int canal = nota.Canal;
              //separa el tiempo en cada canal
              if (tiempo_canal.ContainsKey(canal)){
                string xml=  tiempo_canal[canal];
                xml += "< nota duracion ="+nota.Tiempo+" frecuencia ="+IntrumentoMusical.getFrecuencia(nota.Nota,nota.Octava)+ "/>\n";
                tiempo_canal[canal]=xml;
              }
              else
              {
                  //crea una nueva categoria si no existe el canal
                  tiempo_canal.Add(canal, "< nota duracion =" + nota.Tiempo + " frecuencia =" + IntrumentoMusical.getFrecuencia(nota.Nota, nota.Octava) + "/>\n");
              }
          }


          string xml_canal = "";
          foreach (KeyValuePair<int, string> Par in tiempo_canal)
          {
              xml_canal += "< canal numero = "+Par.Key+" >\n";
              xml_canal += Par.Value;
              xml_canal += "</canal>\n";
          }
            



            String script = "<pista nombre=\"" + this.nombre + "\">\n" +
                             xml_canal+    
                            "</pista>\n"; 
            return script;

        }

        public bool guardar()
        { return guardar(this.nombre); }
        public  bool guardar(string nombre)
        {//los crea si no existen

            System.IO.Directory.CreateDirectory(@"C:\FistProjectOLC2");
            System.IO.Directory.CreateDirectory(@"C:\FistProjectOLC2\Tracks");
            string path= System.IO.Path.Combine(@"C:\FistProjectOLC2\Tracks", nombre+".bin");
            FileInfo f= new FileInfo(path);
          
            if (f.Exists) {
                string messageBoxText = "Ya existe una pista con este nombre desea actualizarla?";
                string caption = "Pista ya existe";
                MessageBoxButtons button = MessageBoxButtons.YesNo;
                MessageBoxIcon icon = MessageBoxIcon.Warning;
                DialogResult result=    MessageBox.Show(messageBoxText, caption, button, icon);
                if (result == DialogResult.No) {
                    return false;
                }
             

            }
            try
            {
                FileStream fs = new FileStream(path, FileMode.Create);

                BinaryWriter bw = new BinaryWriter(fs, ASCIIEncoding.UTF8);
                foreach (NotaReproducida nota in this.notasmusicales)
                {
                    bw.Write(nota.Canal);
                    bw.Write(nota.Octava);
                    bw.Write(nota.Nota);
                    bw.Write(nota.Tiempo);
                }
                bw.Close();
                return true;
            }catch(System.Exception ){
                return false;
            }
            
        }

        List<NotaReproducida> notasmusicales;

        public List<NotaReproducida> Notasmusicales
        {
            get { return notasmusicales; }
            set { notasmusicales = value; }
        }
        public Pista() {
            notasmusicales = new List<NotaReproducida>();
        }

        public void add(String nota, int octava, int tiempo, int canal)
        {
            add(IntrumentoMusical.Nota_txt_to_num(nota), octava, tiempo, canal);
        }
        public void add(int nota, int octava, int tiempo, int canal) {
            NotaReproducida notaObj = new NotaReproducida();
            notaObj.Canal = canal;
            notaObj.Tiempo = tiempo;
            notaObj.Octava = octava;
            notaObj.Nota = nota;
            add(notaObj);
        }
        public void add(NotaReproducida nota)
        {
            if (nota != null) {
                notasmusicales.Add(nota);
            }

        }
        /// <summary>
        /// Se debe llamar el tiempo cuando se a terminado de introducir todas las
        /// notas que lleven la pista.
        /// </summary>
        public void calcularTiempo() {
          Dictionary<int, int> tiempo_canal = new Dictionary<int, int>();
          duracionms = 0;
          foreach (NotaReproducida nota in notasmusicales) {

              int canal = nota.Canal;
              //separa el tiempo en cada canal
              if (tiempo_canal.ContainsKey(canal))
              {
                  int tiempo = tiempo_canal[canal];
                  tiempo_canal[canal] = tiempo + nota.Tiempo;
              }
              else {
                  //crea una nueva categoria si no existe el canal
                  tiempo_canal.Add(canal, nota.Tiempo);
              }
              //verifica si el tiempo del canal actual es mayor, que 
              //el tiempo maximo de canales
              if (tiempo_canal[canal] > duracionms)
              {
                  duracionms = tiempo_canal[canal];
              }
          }


        }
    }
}
